import { FC, ReactElement, memo, useState, useCallback, useMemo } from "react";
import { Caption } from "../Text";
import { Container, DateTimeShow, TimeIcon } from "./styled";
import DatePicker from "./DatePicker";
import TimePicker from "./TimePicker";
import { monthOperation } from "./utils";
interface IProps {
  onSubmit?: (dateTime: IDateTime) => void;
  timePicker?: boolean;
  noShadow?: boolean;
  defaultDateTime?: IDateTime;
  style?: React.CSSProperties;
}

const date = new Date();
export interface IDateTime {
  year: number;
  month: number;
  day: number;
  hour: number;
  minutes: number;
}

const initialDateTime: IDateTime = {
  year: date.getFullYear(),
  month: date.getMonth() + 1,
  day: date.getDate(),
  hour: date.getHours(),
  minutes: date.getMinutes(),
};

const DateTimePicker: FC<IProps> = ({
  onSubmit,
  timePicker,
  noShadow,
  defaultDateTime = {},
  style,
}): ReactElement => {
  const dateTime = useMemo(
    () => ({ ...initialDateTime, ...defaultDateTime }),
    [defaultDateTime]
  );
  const [isPicker, setIsPicker] = useState(false);
  const [timePickerState, setTimePickerState] = useState(false);
  const [DateTime, setDateTime] = useState(dateTime);
  const [selectedDate, setSelectedDate] = useState(dateTime);

  const backToToday = useCallback(() => {
    setDateTime(initialDateTime);
    setSelectedDate(initialDateTime);
  }, []);

  const handlePicker = useCallback(() => {
    setIsPicker(true);
    setTimePickerState(false);
  }, []);
  //取消选择
  const cancelPicker = useCallback(() => {
    setIsPicker(false);
    backToToday();
  }, [backToToday]);
  //关闭选择
  const closePicker = useCallback(() => {
    setIsPicker(false);
  }, []);
  // 日期选择时 左右切换月份
  const toggleMonth = useCallback(
    num => () => {
      setDateTime(prev => monthOperation(prev, num));
    },
    [setDateTime]
  );

  const selectDay = useCallback(
    day => () => {
      //日期会有年和月的区分

      setDateTime(prev => {
        const date = { ...prev };
        date.day = day;
        setSelectedDate(date);
        return date;
      });
    },
    []
  );
  //月份选择时 点击确定 设置月份
  const selectMonth = useCallback(month => {
    setDateTime(prev => {
      const date = { ...prev };
      date.month = month;
      return date;
    });
  }, []);
  //年份选择时 点击确定 设置年
  const selectYear = useCallback(year => {
    setDateTime(prev => {
      const date = { ...prev };
      date.year = year;
      return date;
    });
  }, []);

  const selectedTime = useCallback(
    (time: { [key: string]: number }) => {
      closePicker();
      const dateTime = { ...DateTime, ...time };
      setDateTime(dateTime);
      setSelectedDate(dateTime);
      // console.log(dateTime);
      onSubmit && onSubmit(dateTime);
    },
    [DateTime, closePicker, onSubmit]
  );

  const makeTrue = useCallback(() => {
    //如果开启时间选择的话 进入时间选择器
    if (timePicker) {
      setTimePickerState(true);
    } else {
      closePicker();
      setSelectedDate(DateTime);
      onSubmit && onSubmit(DateTime);
    }
  }, [DateTime, closePicker, onSubmit, timePicker]);

  const DateTimeShowComp = useMemo(() => {
    const { year, month, day, hour, minutes } = selectedDate;
    return (
      <DateTimeShow onClick={handlePicker}>
        <Caption size='1rem'>
          {`${year}/${month}/${day}${timePicker ? ` ${hour}:${minutes}` : ""}`}
        </Caption>
        <TimeIcon />
      </DateTimeShow>
    );
  }, [selectedDate, handlePicker, timePicker]);

  const cancelTimePicker = useCallback(() => {
    setTimePickerState(false);
  }, []);

  // 这样 year month 等状态改变时 timePicker不必重新渲染
  const MemoTimePicker = useMemo(
    () => (
      <TimePicker
        status={timePickerState}
        defaultHour={DateTime.hour}
        defaultMinutes={DateTime.minutes}
        selectedTime={selectedTime}
        cancelTimePicker={cancelTimePicker}
      />
    ),
    [
      DateTime.hour,
      DateTime.minutes,
      cancelTimePicker,
      selectedTime,
      timePickerState,
    ]
  );

  return (
    <Container style={style}>
      {DateTimeShowComp}
      {isPicker ? (
        <>
          <DatePicker
            DateTime={DateTime}
            selectDay={selectDay}
            cancelPicker={cancelPicker}
            toggleMonth={toggleMonth}
            backToToday={backToToday}
            selectMonth={selectMonth}
            selectYear={selectYear}
            makeTrue={makeTrue}
            noShadow={noShadow}
          />
          {MemoTimePicker}
        </>
      ) : null}
    </Container>
  );
};

export default memo(DateTimePicker);
